package com.relytosoft.mizar.media.analyze.services.controller.structure;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.relytosoft.dubhe.common.core.base.page.PageQuery;
import com.relytosoft.dubhe.common.core.exception.ServiceException;
import com.relytosoft.dubhe.common.core.object.ResponseResult;
import com.relytosoft.dubhe.common.core.utils.CommonUtils;
import com.relytosoft.dubhe.common.log.annotation.OpLog;
import com.relytosoft.dubhe.common.log.enums.OpTypeEnum;
import com.relytosoft.mizar.media.analyze.api.entity.structure.AyStructureTask;
import com.relytosoft.mizar.media.analyze.api.entity.structure.AyStructureTaskSon;
import com.relytosoft.mizar.media.analyze.api.pojo.dto.AyStructureTaskSonDto;
import com.relytosoft.mizar.media.analyze.api.pojo.dto.AyTaskIdDto;
import com.relytosoft.mizar.media.analyze.api.pojo.query.AyStructureTaskSonQuery;
import com.relytosoft.mizar.media.analyze.api.pojo.vo.AyBatchVo;
import com.relytosoft.mizar.media.analyze.api.pojo.vo.AyCameraVo;
import com.relytosoft.mizar.media.analyze.services.service.structure.AyStructureTaskService;
import com.relytosoft.mizar.media.analyze.services.service.structure.AyStructureTaskSonService;
import com.relytosoft.mizar.media.common.enums.DeleteStatusEnum;
import com.relytosoft.mizar.media.common.enums.TaskStatusEnum;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author: zyc
 * @version: v1.0
 * @description: com.relytosoft.mizar.analyze.structure.services.controller
 * @Date: 2022/5/13 9:52
 */
@Api(tags = {"结构化分析子任务"})
@RestController
@RequestMapping("analyze/structure/task/son")
public class AyStructureTaskSonController {

    @Resource
    private AyStructureTaskService structureTaskService;
    @Resource
    private AyStructureTaskSonService structureTaskSonService;


    @SaCheckPermission("structure:task:son:insert")
    @OpLog(msg = "创建结构化分析子任务", opType = OpTypeEnum.INSERT)
    @ApiOperation("创建结构化分析子任务")
    @PostMapping({"/insert"})
    public ResponseResult<AyBatchVo> insert(@RequestBody AyStructureTaskSonDto ayStructureTaskSonDto) {
        if (ayStructureTaskSonDto.getStructureTaskId() == null || ayStructureTaskSonDto.getStructureTaskId() == 0) {
            throw new ServiceException("任务ID为空！");
        }
        List<AyCameraVo> ayCameraVos=ayStructureTaskSonDto.getAyCameraVos();
        if(!validateCamera(ayCameraVos)){
            throw new ServiceException("任务设备参数不完整！");
        }

        AyStructureTask ayStructureTask = structureTaskService.getById(ayStructureTaskSonDto.getStructureTaskId());
        if (ayStructureTask == null || ayStructureTask.getIsDeleted() == DeleteStatusEnum.DELETED.getValue()) {
            throw new ServiceException("任务不存在！");
        }
        AyBatchVo ayBatchVo=structureTaskSonService.insertAyStructureTaskSon(ayStructureTaskSonDto, ayStructureTask.getName());
        if(ayBatchVo.getSuccess()>0){
            structureTaskService.taskStatusHandle(ayStructureTaskSonDto.getStructureTaskId(),TaskStatusEnum.CREATED.getValue());
        }
        return ResponseResult.ok(ayBatchVo);
    }

    @SaCheckPermission("structure:task:son:delete")
    @OpLog(msg = "删除结构化分析子任务", opType = OpTypeEnum.DELETE)
    @ApiOperation("删除结构化分析子任务")
    @PutMapping({"/delete"})
    public ResponseResult<Void> delete(@RequestBody List<Integer> ids) {
        if (ids.isEmpty()) {
            return ResponseResult.fail("请选择需要删除的子任务");
        }
        boolean deleteRes = structureTaskSonService.deleteAyStructureTaskSon(ids);
        if (deleteRes) {
            //异常任务删除时需联动更新主任务状态
            List<AyStructureTaskSon> taskSonList=structureTaskSonService.selectUnusualTaskSons(ids);
            if(!taskSonList.isEmpty()){
                //有异常的子任务时，需查询对应的主任务是否还有其它未删除的异常任务
                List<Integer> mainTaskIds=taskSonList.stream().map(AyStructureTaskSon::getStructureTaskId).collect(Collectors.toList());
                for (Integer id:mainTaskIds){
                    structureTaskService.updateStatusByDeleteUnusual(id);
                }
            }
            return ResponseResult.ok();
        }
        return ResponseResult.fail("任务不符合删除条件！");
    }

    @SaCheckPermission("structure:task:son:start")
    @OpLog(msg = "启动结构化分析子任务", opType = OpTypeEnum.OTHER)
    @ApiOperation("启动结构化分析子任务")
    @PostMapping({"/start"})
    public ResponseResult<AyBatchVo> start(@RequestBody AyTaskIdDto taskIdDto) {
        if (taskIdDto.getIds().isEmpty()) {
            throw new ServiceException("请选择需要启动的子任务！");
        }
        if(taskIdDto.getParentId()==null||taskIdDto.getParentId()<=0){
            throw new ServiceException("主任务ID不能为空！");
        }
        AyBatchVo ayBatchVo = new AyBatchVo();
        ayBatchVo.setTotal(taskIdDto.getIds().size());
        //根据ID获取可启动的子任务
        List<AyStructureTaskSon> ayStructureTaskSons = structureTaskSonService.selectCanStartTaskSonList(taskIdDto.getIds(), taskIdDto.getParentId());

        if (ayStructureTaskSons.isEmpty()) {
            ayBatchVo.setSuccess(0);
            ayBatchVo.setError(taskIdDto.getIds().size());
            ayBatchVo.setErrorMsg(Collections.singletonList("没有符合条件的子任务"));
            return ResponseResult.ok(ayBatchVo);
        }

        List<AyStructureTaskSon> deleteTaskSons = new ArrayList<>();
        List<AyStructureTaskSon> insertTaskSons = new ArrayList<>();
        List<AyStructureTaskSon> startTaskSons = new ArrayList<>();

        structureTaskSonService.buildDeleteAndStartTaskSon(ayStructureTaskSons,deleteTaskSons,insertTaskSons);
        structureTaskSonService.buildStartTaskSon(ayStructureTaskSons,startTaskSons);

        boolean deleteAndStartRes=false;
        boolean startRes=false;
        Integer succ=0;
        Integer err=0;
        if (!deleteTaskSons.isEmpty()) {
            //删除并启动任务
            deleteAndStartRes = structureTaskSonService.deleteAndStartTaskSonList(deleteTaskSons, insertTaskSons,null);
            if (deleteAndStartRes) {
                succ+=deleteTaskSons.size();
            } else {
                err+=deleteTaskSons.size();
            }
        }
        if (!startTaskSons.isEmpty()) {
            //启动任务
            startRes = structureTaskSonService.startTaskSonList(startTaskSons,null);
            if (startRes) {
                succ+=startTaskSons.size();
            } else {
                err+=startTaskSons.size();
            }
        }
        if(succ>0){
            structureTaskService.taskStatusHandle(taskIdDto.getParentId(),TaskStatusEnum.CREATED.getValue());
            ayBatchVo.setErrorMsg(Collections.singletonList("符合条件的任务已启动成功"));
        }
        else{
            ayBatchVo.setErrorMsg(Collections.singletonList("任务启动失败"));
        }
        ayBatchVo.setSuccess(succ);
        ayBatchVo.setError(err);
        if(deleteAndStartRes){
            //发送消息
            insertTaskSons.stream().forEach(a->structureTaskSonService.sendInsertTaskMsg(a));
        }
        if(startRes){
            //发送消息
            startTaskSons.stream().forEach(a->structureTaskSonService.sendInsertTaskMsg(a));
        }

        return ResponseResult.ok(ayBatchVo);
    }

    @SaCheckPermission("structure:task:son:stop")
    @OpLog(msg = "停止结构化分析子任务", opType = OpTypeEnum.OTHER)
    @ApiOperation("停止结构化分析子任务")
    @PostMapping({"/stop"})
    public ResponseResult<AyBatchVo> stop(@RequestBody AyTaskIdDto taskIdDto) {
        if (taskIdDto.getIds().isEmpty()) {
            throw new ServiceException("请选择需要启动的子任务！");
        }
        if(taskIdDto.getParentId()==null||taskIdDto.getParentId()<=0){
            throw new ServiceException("主任务ID不能为空！");
        }
        AyBatchVo ayBatchVo = new AyBatchVo();
        ayBatchVo.setTotal(taskIdDto.getIds().size());

        //根据ID获取可停止的子任务
        List<AyStructureTaskSon> ayStructureTaskSons = structureTaskSonService.selectCanStopTaskSonList(taskIdDto.getIds(), taskIdDto.getParentId());

        if (ayStructureTaskSons.isEmpty()) {
            ayBatchVo.setSuccess(0);
            ayBatchVo.setError(taskIdDto.getIds().size());
            ayBatchVo.setErrorMsg(Collections.singletonList("没有符合条件的子任务"));
            return ResponseResult.ok(ayBatchVo);
        }

        List<AyStructureTaskSon> stopTaskSons = new ArrayList<>();
        structureTaskSonService.buildStopTaskSon(ayStructureTaskSons,stopTaskSons);

        boolean stopRes=structureTaskSonService.stopTaskSonList(stopTaskSons,null);
        if(stopRes){
            for (AyStructureTaskSon taskSon:stopTaskSons){
                if(StrUtil.isNotEmpty(taskSon.getTaskId())){
                    //发送删除任务消息
                    structureTaskSonService.sendDeleteTaskMsg(taskSon.getTaskId());
                }
            }
            //主任务停止联动状态处理
            structureTaskService.taskStatusHandle(taskIdDto.getParentId(),TaskStatusEnum.FINISHED.getValue());
            ayBatchVo.setSuccess(stopTaskSons.size());
            ayBatchVo.setError(taskIdDto.getIds().size()-stopTaskSons.size());
            ayBatchVo.setErrorMsg(Collections.singletonList("符合条件的子任务已停止成功"));
        }
        else{
            ayBatchVo.setSuccess(0);
            ayBatchVo.setError(taskIdDto.getIds().size());
            ayBatchVo.setErrorMsg(Collections.singletonList("子任务停止失败"));
        }
        return ResponseResult.ok(ayBatchVo);
    }

    @SaCheckPermission("structure:task:son:list")
    @OpLog(msg = "查询结构化分析子任务列表", opType = OpTypeEnum.SELECT)
    @ApiOperation("查询结构化分析子任务列表")
    @GetMapping({"/list"})
    public ResponseResult<Map<String, Object>> select(AyStructureTaskSonQuery ayStructureTaskSonQuery, PageQuery pageQuery) {
        if(ayStructureTaskSonQuery.getStructureTaskId()==null||ayStructureTaskSonQuery.getStructureTaskId()<=0){
            throw new ServiceException("主任务ID参数异常");
        }
        return ResponseResult.ok(CommonUtils.getPageData(structureTaskSonService.selectAyStructureTaskSonPageList(pageQuery, ayStructureTaskSonQuery)));
    }
    private boolean validateCamera(List<AyCameraVo> cameraVos){
        if(cameraVos.isEmpty()){
            return false;
        }
        for(AyCameraVo cameraVo:cameraVos){
            if(StrUtil.isEmpty(cameraVo.getCameraId())||StrUtil.isEmpty(cameraVo.getCameraName())||StrUtil.isEmpty(cameraVo.getVideoUrl())){
                return false;
            }
        }
        return true;
    }
}
